package edu.pw.treegrid.server.view;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import au.com.bytecode.opencsv.CSVWriter;
import edu.pw.treegrid.server.filter.Filter;
import edu.pw.treegrid.server.message.Hierarchy;
import edu.pw.treegrid.server.message.Path;
import edu.pw.treegrid.server.message.Request;
import edu.pw.treegrid.server.message.ResponseFetchChilds;
import edu.pw.treegrid.server.model.DomainField;
import edu.pw.treegrid.server.model.DomainObject;
import org.apache.log4j.Logger;
import edu.pw.treegrid.server.reportmodel.Report;
import edu.pw.treegrid.server.reportmodel.ReportColumn;
import edu.pw.treegrid.server.reportmodel.ReportSimpleColumn;
import edu.pw.treegrid.server.service.TreeGridService;
import edu.pw.treegrid.shared.ReportColumnType;

/**
 * 
 * Hehehehe
 */
public class CSVView {
	private static Logger log = Logger.getLogger("xalan.reports");
	
	public CSVView(TreeGridService service) {
		super();
		this.service = service;
	}
	
	private TreeGridService service;

	public void setService(TreeGridService service) {
		this.service = service;
	}
	
	public void writeDocument(Report report, Filter filter, OutputStream os) {
		Request request = new Request();
        request.setFilter(filter);
        request.setHierarchy(new Hierarchy());
        Path path = new Path();
        path.addNode("null");
        request.setPath(path);
        request.setReport(report);
        ResponseFetchChilds result = new ResponseFetchChilds();
        service.fetchChilds(request, result);
        
        OutputStreamWriter osw = null;
        try{
        	osw = new OutputStreamWriter(os, "windows-1250");
        } catch(UnsupportedEncodingException ex){
        	log.warn("CSVView.writeDocument(): UnsupportedEncodingException: " + ex.getMessage());
        	return;
        }
        
        CSVWriter writer = new CSVWriter(osw,(char)';');
        //ResultSetHelperServicePl rsh = new ResultSetHelperServicePl();
        
        DecimalFormat decimalFormat = new DecimalFormat();
        
        
        List<ReportColumn> columns = report.getColumns();
        Map<ReportColumn, Integer> reportColumnToDomainFieldIdx = new HashMap<ReportColumn, Integer>();
                
        int rowNumber = 0;
        String[] csvRowCells = null;
        for(DomainObject object : result.getDomainObjects()) {
        	int cellNumber = 0;
        	
        	//Wyswietl naglowek:
        	if(rowNumber == 0) {
        		int idx = 0;
        		for(DomainField df : object.getDomainField()) {
                	if(!columns.contains(df.getReportColumn())){
                		log.warn("Column not found for CSV export in report " + report.getId() + ": " + df.getReportColumn().getName());
                	}else{
                		reportColumnToDomainFieldIdx.put(df.getReportColumn(), idx);
                    	++idx;
                	}
                }
        		
        		csvRowCells = new String[object.getDomainField().size()];
        		cellNumber = 0;
        		for(ReportColumn rc: columns){
        			DomainField df = object.getDomainField().get(reportColumnToDomainFieldIdx.get(rc));
        			
        			ReportSimpleColumn rsc = df.getReportColumn().getReportSimpleColumn();
        			
        			csvRowCells[cellNumber] = service.getColumnTitle(rsc);
        			
            		cellNumber++;
        		}
        		writer.writeNext(csvRowCells);
        		
        		rowNumber++;
        	}
        	
        	for(int i=0; i<csvRowCells.length; ++i){
        		csvRowCells[i] = null;
        	}
        	
        	//Wyswietl dane
        	cellNumber = 0;
        	for(ReportColumn rc: columns){
    			DomainField df = object.getDomainField().get(reportColumnToDomainFieldIdx.get(rc));
    			
        		ReportSimpleColumn rsc = df.getReportColumn().getReportSimpleColumn();
        		Object cellValue = df.getValue();
        		
        		String cellStringValue;
        		
        		if(rsc.getType() == ReportColumnType.INTEGER){
        			decimalFormat.applyPattern("0");
        			cellStringValue = cellValue != null ? decimalFormat.format(cellValue) : "";
        		} else if(rsc.getType() == ReportColumnType.FLOAT) {
        			decimalFormat.applyPattern("0.00");
        			cellStringValue = cellValue != null ? decimalFormat.format(cellValue) : "";
        		} else {
        			cellStringValue = cellValue != null ? cellValue.toString() : "";
        		}
        		csvRowCells[cellNumber] = cellStringValue;
        		
        		cellNumber++;
        	}
        	
        	writer.writeNext(csvRowCells);
        	
        	rowNumber++;
        }
        
        try{
        	writer.flush();
        	writer.close();
        	osw.flush();
        	osw.close();
        }catch(IOException ex){
        	log.warn("CSVView.writeDocument(): IOException: " + ex.getMessage());
        }
	}
}
